<template>
  <view class="ve-input-number-wrapper">
    <input
      class="number-input"
      :type="type"
      :model-value="inputVal"
      :style="{ paddingRight: showClear && !disabled ? '48rpx' : '0' }"
      :class="disabled ? 'disabled' : ''"
      :disabled="disabled"
      :placeholder-style="placeholderStyle"
      :placeholder="placeholder"
      :focus="focus"
      @blur="blur"
    />
    <view class="clear-wrap" v-if="showClear && !disabled">
      <ve-icon name="icon-clear" size="32" @click="clearFn" />
    </view>
  </view>
</template>

<script>
  export default {
    props: {
      modelValue: {
        type: [String, Number],
      },
      type: {
        type: String,
        default: 'digit',
      },
      min: {
        type: Number,
        default: 0,
      },
      max: {
        type: Number,
        default: 99999999.99,
      },
      precision: {
        type: Number,
        default: 0,
      },
      disabled: {
        type: Boolean,
        default: false,
      },
      placeholder: {
        type: String,
        default: '请输入',
      },
      placeholderStyle: {
        type: String,
        default: 'color: #9ea5bb',
      },
      allowClear: {
        type: Boolean,
        default: true,
      },
    },
    data() {
      return {
        focus: false,
      }
    },
    emits: ['update:modelValue', 'change', 'blur', 'clear'],
    computed: {
      showClear() {
        return this.allowClear && (this.inputVal || (typeof this.inputVal == 'number' && this.inputVal === 0))
      },
      inputVal: {
        set(val) {
          this.$emit('update:modelValue', val)
          this.$emit('change', val)
        },
        get() {
          let val = this.modelValue
          if ((val || val === 0) && this.precision > 0) {
            return val.toFixed(this.precision)
          } else {
            return val
          }
        },
      },
    },
    methods: {
      blur(e) {
        this.$nextTick(() => {
          this.inputVal = this.verifyValue(e.detail.value)
          this.$emit('blur', this.verifyValue(e.detail.value))
        })
      },
      verifyValue(value) {
        const { max, min, precision } = this.$props
        let newVal = Number(value)
        if (value == undefined || value == null || value == '' || Number.isNaN(newVal)) {
          return ''
        }
        newVal = this.toPrecision(newVal, precision)
        if (newVal > max || newVal < min) {
          newVal = newVal > max ? max : min
        }
        return newVal
      },
      toPrecision(num, pre) {
        if (pre === 0) return Math.round(num)
        let snum = String(num)
        const pointPos = snum.indexOf('.')
        if (pointPos === -1) return num
        const nums = snum.replace('.', '').split('')
        const datum = nums[pointPos + pre]
        if (!datum) return num
        const length = snum.length
        if (snum.charAt(length - 1) === '5') {
          snum = `${snum.slice(0, Math.max(0, length - 1))}6`
        }
        return Number.parseFloat(Number(snum).toFixed(pre))
      },
      clearFn() {
        this.inputVal = ''
        this.focus = true
        this.$emit('clear', this.inputVal)
      },
    },
  }
</script>

<style lang="less" scoped>
  .disabled {
    color: rgba(205, 206, 208, 1);
  }
  .ve-input-number-wrapper {
    width: 100%;
    position: relative;
  }
  .number-input {
    text-align: right;
    line-height: 36rpx;
  }
  .clear-wrap {
    width: 48rpx;
    height: 100%;
    position: absolute;
    right: 0;
    top: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }
</style>
